using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using CGraph.Transactions;
using CGraph.Generic;

namespace CGraph_Tests
{
    public class TestData
    {
        public static readonly string DataDir = @"..\\..\\..\\..\\data\\";
    }

    public abstract class SerializationTestBase : IDisposable
    {
        protected virtual string TestFilename
        {
            get { return "test"; }
        }
        protected virtual void ClearTestFile( string inFName )
        {
            if ( File.Exists( inFName ) )
                try { File.Delete(inFName); }
                catch { }
        }
        protected abstract void SetupData();
        protected abstract void TestData();
        protected abstract void SaveData( Stream fname );
        protected abstract void LoadData( Stream fname );
        public virtual void RunTest()
        {
            SetupData();
            TestData();
            Stream memoryStream = new MemoryStream();
            SaveData(memoryStream);
            long len = memoryStream.Length;
            memoryStream.Seek(0, SeekOrigin.Begin);
            LoadData(memoryStream);
            TestData();
        }

        public virtual void Dispose()
        {
            ClearTestFile(Path.GetFullPath(TestFilename));
            GC.SuppressFinalize(this);
        }

        public static void RunTest<TType>() where TType : SerializationTestBase, new()
        {
            using (TType test = new TType())
            {
                test.RunTest();
            }
        }
    }

    public abstract class TransactionTest : IDisposable
    {
        protected TransactionSystem m_system = new TransactionSystem();
        protected IActionList m_transaction;


        protected virtual void Initialize()
        {
        }
        protected abstract void TestPrecondition();
        protected abstract void DoOperation();
        protected abstract void TestPostcondition();

        public virtual void RunTest()
        {
            Initialize();
            TestPrecondition();
            using (TransactionHandle hdl = m_system.OpenTransaction("test"))
            {
                m_transaction = (IActionList)hdl.Transaction.Value;
                DoOperation();
            }
            TestPostcondition();
            m_transaction.Undo();
            TestPrecondition();
            m_transaction.Do();
            TestPostcondition();
        }

        #region IDisposable Members

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

        #endregion

        public static void RunTest<TType>() where TType : TransactionTest, new()
        {
            using (TType test = new TType())
            {
                test.RunTest();
            }
        }
    }
    public abstract class TransactionSerializationTest : TransactionTest
    {
        protected abstract void SaveData(Stream fname);
        protected abstract void LoadData(Stream fname);
        public override void RunTest()
        {
            base.RunTest();
            Stream memoryStream = new MemoryStream();
            SaveData(memoryStream);
            long len = memoryStream.Length;
            memoryStream.Seek(0, SeekOrigin.Begin);
            LoadData(memoryStream);
            TestPostcondition();
        }
    }
}
